大家好我是阿華,今天來跟大家聊聊Scope,作用域:
來自MDN說:
作用域是目前的執行上下文(Context),值和表達式在其中「可見」或可被存取。如果一個變數或表達式不在目前的作用域中,那麼它是不可用的。作用域也可以構成層級結構,子作用域可以存取父作用域,反過來則不行。
當 JavaScript 程式碼被執行一開始時,就會創建一個全域執行環境,被定義在函式或塊級以外的變數,就會屬於全局作用域,這些變數也被稱之為全域變數 (Global variable),在程式碼中的任何地方都能被使用到。以下例子的 a 值就是在全局作用域的全域變數。
var a = "全域作用域";
function call() {
console.log(a); // 全域作用域
a = "全域作用域~~";
}
call();
console.log(a); // 全域作用域~~
由函數所創建的作用域
function scope() {
let a = "函數作用域";
console.log(a); // 函數作用域
}
// a 在此處不可用,因為 a 是函數作用域,即便用var宣告亦然不可用,因為被var有函數作用域
ES6 之後才出現,被定義在一個塊級中 {} ,
如下面例子,在 if else 判斷式中,就屬於塊級作用域。要注意的是,只有 let 和 const 定義的變數會屬於塊級作用域,如果是 var 定義的變數會是只有函數作用域。
function checkScope() {
if (true) {
let a = "塊級作用域";
var b = "函數作用域"; // var宣告,切分變數範圍是function
} else {
// a 變數屬於 if 判斷式中的塊級作用域,在此處不可用
// b 變數屬於 check 函數的作用域,在此處可用
console.log(b); // 函數作用域
}
// a 在此處不可用,b 在此處可用
}
// a,b 在此處不可用
當 JavaScript 使用每一個變數的時候,會先嘗試在當前作用域中尋找該變數,若在當前的作用域找不到該變數,會一直往父層作用域尋找,直到全局作用域還是沒找到,就會直接報錯,這一層一層的關係,連起來就是作用域鏈。讓我們透過以下程式碼來了解:
let a = 100;
function find() {
// 在 find 函數作用域中沒有變數 a,於是透過作用域鏈往父層尋找,
// 在這邊的父層是全域,也就找到了 a 變數
console.log(a); // 100
}
find();
相信經過上面的整理與例子,大家能夠初步的了解作用域(Scope)與作用域鏈 (Scope Chain)是什麼,下回見摟~